package com.sean.filter;

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.Map.Entry;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.log4j.Logger;

public class EnviromentFilter implements Filter {
    private final Logger logger = Logger.getLogger(EnviromentFilter.class);

    private static final String ENV_CONFIGURATION = "envConfiguration";
    private ServletContext context = null;

    public void destroy() {
	// TODO Auto-generated method stub

    }

    public void doFilter(ServletRequest request, ServletResponse response,
	    FilterChain chain) throws IOException, ServletException {
	String env = context.getInitParameter(ENV_CONFIGURATION);

	if (null == env || env.equals("")) {
	    return;
	}
	logger.debug("Begin load properties");

	final Properties globalProps = new Properties();

	String[] props = env.split(",");
	for (String prop : props) {
	    try {
		if (logger.isDebugEnabled()) {
		    logger.debug("Load enviroment variable from file " + prop);
		}
		InputStream is = findProperties(prop);
		if (is != null) {
		    globalProps.load(is);
		} else {
		    logger.error("Can't load properties");
		}
	    } catch (IOException e) {
		logger.error("Load enviroment variables from " + prop
			+ " failed!", e);
	    }
	}

	// Set them all in context variable. Be careful for conflict
	try {
	    for (Entry entry : globalProps.entrySet()) {
		String keyStr = (String) entry.getKey();
		String actualKey = keyStr.replaceAll("\\.", "_");
		logger.debug(MessageFormat.format(
			"Load variable {0}, you can access it by {1}", keyStr,
			actualKey));
		context.setAttribute(actualKey, entry.getValue());
	    }
	} catch (Throwable t) {
	    t.printStackTrace();
	}

	logger.debug("............. Load ...............");
	chain.doFilter(request, response);
    }

    private InputStream findProperties(String loc) {
	InputStream is = null;
	logger.debug("Load " + prefixClass() + loc + " ok. ----------");
	is = getClass().getResourceAsStream(prefixClass() + loc);
	logger.debug("Load " + loc + " ok. ----------");
	return is;
    }

    public void init(FilterConfig filterConfig) throws ServletException {
	context = filterConfig.getServletContext();
    }

    private String prefixClass() {
	String sep = "../";
	String[] packageParts = getClass().getPackage().getName().toString()
		.split("\\.");
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < packageParts.length; i++) {
	    builder.append(sep);
	}
	return builder.toString();
    }

}
